package com.lijin.download;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

public class DownLoad {

    public static void main(String[] args) {
        new DownLoad().down(args);
    }

    public void down(String[] args){
        if(args.length < 3){
            throw new RuntimeException("参数依次为：m3u8文件地址、使用的线程数、保存文件的路径、保存文件的名称(默认为下载文件的名称)!");
        }
        String m3u8Url = args[0];
        String threadNum = args[1];
        String savePath = args[2];
        if(StringUtils.isBlank(m3u8Url) || StringUtils.isBlank(threadNum) || StringUtils.isBlank(savePath)){
            throw new RuntimeException("参数依次为：m3u8文件地址、使用的线程数!");
        }

        Integer parseNum ;
        try {
            parseNum = Integer.parseInt(threadNum);
        } catch (Exception e) {
            throw new RuntimeException("线程数必须是数字");
        }

        savePath = com.lijin.download.FileUtils.notExist2Create(savePath, "c:/download");

        if(parseNum > 24 || parseNum < 0){
            System.err.println("线程数必须大于0并且小于24，当前设置线程数为"+parseNum+"，已将其设置为12");
            parseNum = 12;
        }
        //去掉两边中文和英文的空格
        String extension = FilenameUtils.getExtension(StringUtils.strip(m3u8Url));
        if(!StringUtils.equals(extension, "m3u8")) throw new RuntimeException("下载文件必须是m3u8文件,当前文件为：" + extension);

        //用来存储m3u8中的内容
        String content ;
        try {
            if(m3u8Url.startsWith("http")){
                ByteArrayOutputStream stream = HttpClientUtils.getRequest(m3u8Url);
                content = new String(stream.toByteArray(),"utf-8");
            }else{
                content = IOUtils.toString(Paths.get(m3u8Url).toUri(), "UTF-8");
            }
        } catch (Exception e) {
            throw new RuntimeException("获取m3u8文件异常",e);
        }

        String fileName = args.length > 3? args[3]:FilenameUtils.getBaseName(m3u8Url);
        //获取下载地址的栈对象
        final Set<String> downUrls = com.lijin.download.FileUtils.resolveUrl(content);
        if(downUrls.isEmpty()){
            System.err.println("解析m3u8文件后获取下载路径为空，提交结束当前任务");
            return;
        }
        //  获取需要下载文件的url
        String firstUrl = downUrls.iterator().next();
        //  获取到下载文件的扩展名
        extension = FilenameUtils.getExtension(firstUrl);

        //  设置保存文件的名称
        DownBean downBean = new DownBean(m3u8Url, downUrls, savePath, extension, fileName);

        ThreadPoolExecutor newFixedThreadPool = (ThreadPoolExecutor)Executors.newFixedThreadPool(parseNum);
        for (String url:downBean.getUrls()) {
            newFixedThreadPool.execute(() ->{
                DownLoadUtls.down(url,downBean.getSavePath(),downBean);
            });
        }
        newFixedThreadPool.shutdown();
        while(!newFixedThreadPool.isTerminated()){}
        LinkedList<File> files = (LinkedList)FileUtils.listFiles(new File(downBean.getSavePath()), new String[]{downBean.getExtension()}, false);
        //Collections是一个在Collection上操作的工具类。可以实现对集合元素的排序
        Collections.sort(files,(File o1, File o2) ->{
            return o1.getName().compareTo(o2.getName());
        });
        com.lijin.download.FileUtils.merge(
                files,
                downBean.getMergeNames(),
                new File(downBean.getSavePath(),new StringBuffer(downBean.getSaveFileName()).append(".").append(downBean.getExtension()).toString()),
                true
        );
    }



}
